using System;
using System.Linq;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using System.Text.RegularExpressions;

namespace Widgetsphere.WebUtils
{
	public static class FormatHelper
	{
		#region Methods

		/// <summary>
		/// Determines if the specified string represents a number
		/// </summary>
		internal static bool IsNumeric(string s)
		{
			double i = 0;
			return double.TryParse(s, out i);
		}

		public static int? ToInt32(this string v)
		{
			int retval;
			if (int.TryParse(v, out retval))
				return retval;
			else
				return null;
		}

		public static string GetHost(System.Web.HttpRequest request)
		{
			return GetHost(request, true);
		}

		public static string GetHost(System.Web.HttpRequest request, bool cleanSubDomain)
		{
			try
			{
				var websitePath = "";

#if DEBUG
				//If in DEBUG and not running on prt 80 then we are not running in IIS
				//so get the website path for proper URL creation
				//if (request.Url.Port != 80)
				//{
				//  websitePath = request.Url.AbsolutePath;
				//  if (websitePath.StartsWith("/"))
				//    websitePath = websitePath.Substring(1, websitePath.Length - 1);
				//  int i = websitePath.IndexOf("/");
				//  if (i != -1)
				//    websitePath = websitePath.Substring(0, i + 1);
				//  else
				//    websitePath = "";
				//}
#endif

				var sHost = "";
				if ((request != null) && (request.ServerVariables["HTTP_HOST"] != ""))
					sHost = "http://" + request.ServerVariables["HTTP_HOST"] + "/" + websitePath;
				else if ((request != null) && (request.ServerVariables["HTTP_HOST"] == "")) //This is the default if there is an error
					sHost = "http://www." + System.Configuration.ConfigurationManager.AppSettings["Domain"] + ".com/";

				//Fall back case
				if (sHost == "http:///")
					sHost = "http://www." + System.Configuration.ConfigurationManager.AppSettings["Domain"] + ".com/";

				if (cleanSubDomain && (sHost.Contains("://")))
				{
					//Catch this error
					System.Uri uri = null;
					try
					{
						uri = new System.Uri(sHost);
					}
					catch (Exception ex)
					{
						throw new Exception("Error parsing host name '" + sHost + "'");
					}

					var domainParts = uri.DnsSafeHost.Split('.');
					if ((domainParts.Length == 4) && IsNumeric(domainParts[0]) && IsNumeric(domainParts[1]) &&
							IsNumeric(domainParts[2]) && IsNumeric(domainParts[3]))
					{
						//If this is an IP address then leave it alone
					}
					else if (domainParts.Length == 3)
					{
						var index1 = sHost.IndexOf("://");
						var index2 = sHost.IndexOf(".");
						sHost = sHost.Substring(0, index1 + 3) + "www" + sHost.Substring(index2, sHost.Length - index2);
					}
				}

				sHost = sHost.Replace("https://", "http://");
				return sHost;

			}
			catch (Exception ex)
			{
				throw;
			}
		}

		/// <summary>
		/// Format a phone number for display in US format
		/// </summary>
		public static string FormatPhone(string s)
		{
			if (s == null)
				return "";

			if (s.Length == 10)
			{
				return s.Substring(0, 3) + "-" + s.Substring(3, 3) + "-" + s.Substring(6, 4);
			}
			else if (s.Length == 11)
			{
				return s.Substring(0, 1) + "-" + s.Substring(1, 3) + "-" + s.Substring(4, 3) + "-" + s.Substring(7, 4);
			}
			return s;

		}

		public static string StripToNumber(string s)
		{
			return StripToNumber(s, true);
		}

		public static string StripToNumber(string s, bool includeDecimal)
		{
			if (s == null)
				return "";

			var sb = new StringBuilder();
			foreach (var c in s)
			{
				if (includeDecimal && c == '.')
					sb.Append(c);
				else if ((c != '.') && ('0' <= c) && (c <= '9'))
					sb.Append(c);
			}

			return s;

		}

		public static string FormatEmptyvalue(string s)
		{
			if ((s == null) || (s == ""))
				return "N/A";
			else
				return s;
		}

		/// <summary>
		/// Format a number into a money string with dollar sign and 2 decimals
		/// </summary>
		public static string FormatMoney(string s)
		{
			return FormatMoney(s, true);
		}

		/// <summary>
		/// Format a number into a money string with dollar sign and 2 decimals
		/// </summary>
		public static string FormatMoney(string s, bool zeroIsValid)
		{
			try
			{
				long l = 0;
				if (!string.IsNullOrEmpty(s))
				{
					long.TryParse(s, out l);
				}

				if ((l == 0) && !zeroIsValid)
					return FormatHelper.FormatEmptyvalue("");
				else
					return l.ToString("$###,###,##0");
			}
			catch (Exception ex)
			{
				throw;
			}
		}

		/// <summary>
		/// Format an integer number to a comma seperated number string
		/// </summary>
		public static string FormatNumber(string s)
		{
			try
			{
				long l;
				if (long.TryParse("0" + s, out l))
				{
					return l.ToString("###,###,##0");
				}
				return "";
			}
			catch (Exception ex)
			{
				throw;
			}
		}

		/// <summary>
		/// Replace a string list with sequence '^+^' to a comma
		/// </summary>
		public static string FormatList(string s)
		{
			if (s == null)
				return "";
			try
			{
				return s.Replace("^+^", ", ");
			}
			catch (Exception ex)
			{
				throw;
			}
		}

		/// <summary>
		/// Encode a string to Base64
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		public static string Base64Encode(string data)
		{
			try
			{
				var encData_byte = new byte[data.Length];
				encData_byte = System.Text.Encoding.UTF8.GetBytes(data);
				var encodedData = Convert.ToBase64String(encData_byte);
				return encodedData;
			}
			catch (Exception e)
			{
				throw new Exception("Error in base64Encode" + e.Message);
			}
		}

		/// <summary>
		/// Decode a string from Base64 to a normal string
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		public static string Base64Decode(string data)
		{
			try
			{
				var encoder = new System.Text.UTF8Encoding();
				var utf8Decode = encoder.GetDecoder();

				var todecode_byte = Convert.FromBase64String(data);
				var charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
				var decoded_char = new char[charCount];
				utf8Decode.GetChars(todecode_byte, 0, todecode_byte.Length, decoded_char, 0);
				var result = new String(decoded_char);
				return result;
			}
			catch (Exception e)
			{
				throw new Exception("Error in base64Decode" + e.Message);
			}
		}


		/// <summary>
		/// Regular expression, which is used to validate an E-Mail address.
		/// </summary>
		/// <remarks>http://www.codeproject.com/KB/recipes/EmailRegexValidator.aspx</remarks>
//    public const string MatchEmailPattern =
//        @"^(([\w-]+\.)+[\w-]+|([a-zA-Z]{1}|[\w-]{2,}))@"
//       + @"((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?
//				[0-9]{1,2}|25[0-5]|2[0-4][0-9])\."
//       + @"([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?
//				[0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|"
//       + @"([a-zA-Z]+[\w-]+\.)+[a-zA-Z]{2,4})$";

		//public const string MatchEmailPattern = @"[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}";

		/// <summary>
		/// Determines if the specified email address is valid
		/// </summary>
		/// <param name="email"></param>
		/// <returns></returns>
		public static bool IsValidEmailAddress(string email)
		{
			//string MatchEmailPattern = @"[A-Za-z0-9_%+-]+@[A-Za-z0-9-]+\.[A-Za-z]{2,10}";
			var MatchEmailPattern = @"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?";

			if (email == null) return false;
			if (email.Count(x => x == '@') != 1) return false;
			return Regex.IsMatch(email, MatchEmailPattern);


			//if (email == null)
			//{
			//  return false;
			//}

			//int nFirstAT = email.IndexOf('@');
			//int nLastAT = email.LastIndexOf('@');

			//if ((nFirstAT > 0) && (nLastAT == nFirstAT) &&
			//(nFirstAT < (email.Length - 1)))
			//{
			//  // address is ok regarding the single @ sign
			//  return (Regex.IsMatch(email, @"(\w+)@(\w+)\.(\w+)"));
			//}
			//else
			//{
			//  return false;
			//}
		}

		/// <summary>
		/// Strip off all invalid characters for an XML file node or attribute value
		/// </summary>
		/// <param name="text">The text to clean</param>
		public static string EnsureValidXMLValue(string text)
		{
			var validsmallchars = new byte[] { 10, 13 };
			var sb = new StringBuilder();
			foreach (var c in text)
			{
				//Only CR,LF are valid for chars less than space (32)
				if (c < ' ')
				{
					if (validsmallchars.Contains((byte)c))
						sb.Append(c);
				}
				else
				{
					sb.Append(c);
				}
			}
			return sb.ToString();
		}

		#endregion
		
	}

}